package com.flex.mobile.dao.impl;

import java.sql.ResultSet;
import java.sql.SQLException;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

import javax.sql.DataSource;

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.jdbc.core.RowMapper;
import org.springframework.jdbc.core.simple.ParameterizedRowMapper;
import org.springframework.jdbc.core.simple.SimpleJdbcInsert;
import org.springframework.jdbc.core.simple.SimpleJdbcTemplate;
import org.springframework.stereotype.Service;

import com.flex.mobile.constant.OrderInfoStatusConst;
import com.flex.mobile.constant.OrderInfoTypeConst;
import com.flex.mobile.dao.IGenericDAO;
import com.flex.mobile.dao.model.OrderInfo;
import com.flex.mobile.util.SqlUtil;

@Service("orderInfoDao")
public class OrderInfoDao implements IGenericDAO<OrderInfo> {
   private final SimpleJdbcTemplate template;

   private final SimpleJdbcInsert insertContact;

   @Autowired
   public OrderInfoDao(DataSource dataSource) {
      this.template = new SimpleJdbcTemplate(dataSource);
      this.insertContact = new SimpleJdbcInsert(dataSource).withTableName(
            "ORDER_INFO").usingGeneratedKeyColumns("ID");
   }

   private final RowMapper<OrderInfo> summaryRowMapper = new ParameterizedRowMapper<OrderInfo>() {

      @Override
      public OrderInfo mapRow(ResultSet rs, int rowNum) throws SQLException {
         OrderInfo item = new OrderInfo();
         item.setId(rs.getLong("ID"));
         item.setOrderNo(rs.getString("ORDER_ID"));
         item.setOrderType(rs.getInt("ORDER_TYPE"));
         item.setOrderStatus(rs.getInt("ORDER_STATUS"));
         item.setCreateDate(rs.getTimestamp("CREATE_DATE"));
         item.setFinishDate(rs.getTimestamp("FINISH_DATE"));
         item.setDriverId(rs.getInt("DRIVER_ID"));
         item.setCarId(rs.getString("CAR_ID"));
         item.setOwnerId(rs.getLong("OWNER_ID"));
         item.setTargetTime(rs.getTimestamp("TARGET_TIME"));
         item.setTargetAddress(rs.getString("TARGET_ADDRESS"));
         item.setDestination(rs.getString("DESTINATION"));
         item.setAddMoney(rs.getFloat("ADD_MONEY"));
         item.setFlightNumber(rs.getString("FLIGHT_NUMBER"));
         item.setAirport(rs.getString("AIRPORT"));
         item.setVersion(rs.getInt("VERSION"));
         return item;
      }

   };

   @Override
   public OrderInfo create(OrderInfo item) {
      Map<String, Object> parameters = new HashMap<String, Object>();
      parameters.put("ID", null);
      parameters.put("ORDER_ID", item.getOrderNo());
      parameters.put("ORDER_TYPE", item.getOrderType());
      parameters.put("ORDER_STATUS", item.getOrderStatus());
      parameters.put("FINISH_DATE", item.getFinishDate());
      parameters.put("DRIVER_ID", item.getDriverId());
      parameters.put("OWNER_ID", item.getOwnerId());
      parameters.put("TARGET_TIME", item.getTargetTime());
      parameters.put("TARGET_ADDRESS", item.getTargetAddress());
      parameters.put("DESTINATION", item.getDestination());
      parameters.put("ADD_MONEY", item.getAddMoney());
      parameters.put("FLIGHT_NUMBER", item.getFlightNumber());
      parameters.put("AIRPORT", item.getAirport());
      parameters.put("CREATE_DATE", item.getCreateDate());
      parameters.put("VERSION", 1);
      Number id = this.insertContact.executeAndReturnKey(parameters);
      item.setId(id.longValue());
      return item;
   }

   @Override
   public List<OrderInfo> findAll() {
      return this.template.query("SELECT * FROM ORDER_INFO ",
            this.summaryRowMapper);
   }

   @Override
   public OrderInfo findById(long id) {
      String sql = "select * from ORDER_INFO e " + " where e.id = ? ";
      return this.template.queryForObject(sql, summaryRowMapper, id);
   }

   public List<OrderInfo> findByUserId(long userId) {
      String sql = "select * from ORDER_INFO  "
            + " where owner_id = ? order by create_date desc";
      return this.template.query(sql, summaryRowMapper, userId);
   }

   @Override
   public List<OrderInfo> findByName(String name) {
      // String sql = "select * from ORDER_INFO e" + "where e.NAME  like ?";
      // return this.template.query(sql, summaryRowMapper, "%" + name.trim() +
      // "%");
      return null;
   }

   /***
    * 查询某一类型正在等待受理的订单
    * 
    * @param name
    * @return
    */
   public List<OrderInfo> findWaitingOrderByType(int type) {
      if (type == OrderInfoTypeConst.RESERVED_CALLTAXI) {
         StringBuffer sql = new StringBuffer();
         sql.append(
               "select * from ORDER_INFO e where e.order_status=1 and e.order_type ")
               .append(SqlUtil.inSql(4)).append(" order by create_date desc");
         return this.template.query(sql.toString(), this.summaryRowMapper, 1,
               2, 3, 4);
      } else {
         String sql = "select * from ORDER_INFO e where e.order_status=1 and e.order_type=? order by create_date desc";
         return this.template.query(sql, summaryRowMapper, type);
      }
   }

   public OrderInfo findByOrderId(long orderId) {
      String sql = "select * from ORDER_INFO e " + " where e.ORDER_ID = ? ";
      return this.template.queryForObject(sql, summaryRowMapper, orderId);
   }

   /**
    * 
    * @param orderIds
    * @param type
    * @param status
    * @return
    */
   public List<OrderInfo> findByOrderIds(List<Long> orderIds, int type,
         int status) {
      StringBuffer sql = new StringBuffer();
      sql.append(
            "select * from ORDER_INFO   where order_type = " + type
                  + " and order_status = " + status + " and id ").append(
            SqlUtil.inSql(orderIds.size()));
      return this.template.query(sql.toString(), this.summaryRowMapper,
            orderIds.toArray());
   }

   /**
    * 查找该司机受理成功的单子
    * 
    * @param orderId
    * @return
    */
   public List<OrderInfo> findActivesByDriverId(long driverId) {
      String sql = "select * from ORDER_INFO e "
            + " where e.order_status=? and driver_id=? order by target_time asc";
      return this.template.query(sql, summaryRowMapper,
            OrderInfoStatusConst.ACCEPTED, driverId);
   }

   public List<OrderInfo> findByDriverId(long driverId) {
      String sql = "select * from ORDER_INFO e " + " where e.order_status in("
            + OrderInfoStatusConst.ACCEPTED + ","
            + OrderInfoStatusConst.SUCCESS
            + ") and driver_id=? order by create_date desc";
      return this.template.query(sql, summaryRowMapper, driverId);
   }

   @Override
   public boolean remove(OrderInfo item) {
      int count = this.template.update("DELETE FROM ORDER_INFO WHERE id=?",
            item.getId());
      return count == 1;
   }

   @Override
   public boolean update(OrderInfo item) {
      StringBuffer sql = new StringBuffer();
      sql.append("UPDATE ORDER_INFO SET ORDER_TYPE=?, ORDER_STATUS=?, DRIVER_ID=?,CAR_ID=?, OWNER_ID=?, ");
      sql.append("TARGET_TIME=?,TARGET_ADDRESS=?,DESTINATION=?,ADD_MONEY=?,FLIGHT_NUMBER=?,AIRPORT=?,version=?");
      sql.append(" WHERE id=? and version=?");
      int count = this.template.update(sql.toString(), item.getOrderType(),
            item.getOrderStatus(), item.getDriverId(), item.getCarId(),
            item.getOwnerId(), item.getTargetTime(), item.getTargetAddress(),
            item.getDestination(), item.getAddMoney(), item.getFlightNumber(),
            item.getAirport(), item.getVersion() + 1, item.getId(),
            item.getVersion());
      return count == 1;
   }

}
